//
// Created by gacmy on 2020/7/1.
//

#include "SearchFile.h"
char *fullpath;
vector<string> fileList;

int recordFileFunc1(const char *pathname,const struct stat *statptr,int type){
    if(type == FTW_F){
        if((statptr->st_mode & S_IFMT) == S_IFDIR){
            exit(1);
        }
    }
    int index = strlen(pathname) -1;

    //cout<<pathname<<" len"<<index<<endl;
    int dotIndex = -1;
    while (index--){
        if(pathname[index] == '.'){
            dotIndex = index;
            break;
        }
    }
    if(dotIndex != -1){
        if(strcmp(pathname+dotIndex,".c")==0 ||
                strcmp(pathname+dotIndex,".cpp") == 0 ||
                strcmp(pathname+dotIndex,".h") == 0  ){
            //cout<<"find filename::"<<pathname<<endl;
            fileList.push_back(fullpath);

        }
    }
    //cout<<"dotIndex:"<<dotIndex<<endl;
   // cout<<pathname[strlen(pathname)-1]<<endl;

   // fileList.push_back(pathname);
    return 0;
}
vector<string> execute( char* path){

    myftw(path, reinterpret_cast<int (*)(const char *, const struct state *, int)>(recordFileFunc1));

    return fileList;
}

int myftw(char *pathname,int(*recordFileFunc)(const char*,const struct state*, int)){

    fullpath = static_cast<char *>(malloc(1024));
    strncpy(fullpath,pathname,1024);
    fullpath[1023]=0;
   // cout<<"doPath:"<<fullpath<<endl;

    return (dopath(recordFileFunc));
}

int dopath(int(*recordFileFunc)(const char*,const struct state*, int)){
    struct stat statbuf;
    struct dirent *dirp;
    DIR *dp;
    int ret;
    char *ptr;
    if(lstat(fullpath,&statbuf) < 0){
       // cout<<"file is not state"<<endl;
        return recordFileFunc(fullpath, reinterpret_cast<const struct state *>(&statbuf), FTW_NS);
    }//stat error
    if(S_ISDIR(statbuf.st_mode) == 0){//not a direcoty
        //cout<<"current filename is not dir"<<endl;

        return recordFileFunc(fullpath, reinterpret_cast<const struct state *>(&statbuf), FTW_F);
    }
    //如果是目录则先记录一下目录 然后继续递归
    ptr = fullpath+strlen(fullpath);//指向当前目录路径的末尾
    *ptr++ ='/';
    *ptr = 0;
    if((dp = opendir(fullpath)) == NULL){//can not read directory
      //  cout<<"dir can not read"<<endl;
        return recordFileFunc(fullpath, reinterpret_cast<const struct state *>(&statbuf), FTW_DNR);
    }
    while((dirp = readdir(dp)) != NULL){
        if(strcmp(dirp->d_name,".") == 0 ||
           strcmp(dirp->d_name,"..") == 0)
            continue;
        //fullpathname 进行更新
        strcpy(ptr,dirp->d_name);
       // cout<<"first while:"<<dirp->d_name<<endl;
        dopath(recordFileFunc);
//        if((ret = dopath(recordFileFunc)) != 0)//继续递归遍历目录
//            break;
    }
    ptr[-1] = 0;
    if(closedir(dp) < 0){

    }
    return ret;
}
